home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- // ATLVCL.H - Provides the connective tissue between
- // the ATL framework and VCL components.
- //
- // $Revision: 1.44.3.3 $
- // $Date: 05 Feb 1998 20:22:40 $
- //
- // Copyright (c) 1998 Borland International
- /////////////////////////////////////////////////////////////////////////////
-
- #ifndef __ATLVCL_H_
- #define __ATLVCL_H_
-
- #pragma option push -VF
-
- // These are required due to RTL differences between VC++ and BCB
- //
- #define _ATL_NO_FORCE_LIBS
- #define _ATL_NO_DEBUG_CRT
-
- // Defines _ASSERTE et al.
- //
- #include <utilcls.h>
-
- // Delta for remapping messages for VCL compatibility
- //
- #if !defined(OCM_BASE)
- #define OCM_BASE (int)(8192)
- #endif
-
- #if !defined(__ATLBASE_H)
- #include <atl\atlbase.h>
- #endif
-
- #include <sysdefs.h>
- #include <objbase.h>
- #include <dstring.h>
- #include <wstring.h>
- #include <sysutils.hpp>
- #include <cguid.h>
- #include <dir.h>
-
- // Externs
- //
- extern void* SaveInitProc;
-
- // Prototype of routines implemented in ATLVCL.CPP
- //
- bool __fastcall AutomationTerminateProc();
- void __fastcall SaveVCLComponentToStream(TComponent *instance, LPSTREAM pStream);
- void __fastcall LoadVCLComponentFromStream(TComponent *instance, LPSTREAM pStream);
- TWinControl* CreateReflectorWindow(HWND parent, Controls::TControl* Control);
-
- // Forward Ref. (Avoids explicit inclusion of AXCTRLS.HPP)
- //
- namespace Axctrls
- {
- extern PACKAGE HWND __fastcall ParkingWindow(void);
- }
-
- // Forward Ref. (Avoids explicit inclusion of BDEPROV.HPP)
- //
- namespace Bdeprov
- {
- extern PACKAGE void __fastcall UseBdeProv(void);
- };
-
-
- // Default MiscStatus Flags of Object
- //
- const DWORD dwDefaultControlMiscFlags = OLEMISC_RECOMPOSEONRESIZE | OLEMISC_CANTLINKINSIDE |
- OLEMISC_INSIDEOUT | OLEMISC_ACTIVATEWHENVISIBLE |
- OLEMISC_SETCLIENTSITEFIRST;
-
- // Declares routine that returns OLEMISC_xxxx Values
- //
- #define DECLARE_OLEMISC_FLAGS(flags) \
- static DWORD _GetObjectMiscStatus() \
- { \
- return flags; \
- }
-
- // Declares tables of Verbs (Actions) support by object
- //
- #define BEGIN_VERB_MAP() \
- static const OLEVERB* _GetVerbs() \
- { \
- static const OLEVERB _verbs[]= \
- {
-
- #define VERB_ENTRY_EX(verbId, verbString, mfFlags, verbAttrib) \
- {verbId, verbString, mfFlags, verbAttrib },
-
- #define VERB_ENTRY(verbId, verbString) \
- VERB_ENTRY_EX(verbId, verbString, 0 /* No MF_xxxx Flags */, OLEVERBATTRIB_ONCONTAINERMENU)
-
- #define END_VERB_MAP() \
- { 0, 0, 0, 0 } \
- }; \
- return _verbs; \
- };
-
-
- // TVclPtr wraps a pointer in order to perform lifetime mangement.
- //
- //
- // Template auto_ptr holds onto a pointer obtained via new and deletes that
- // object when it itself is destroyed (such as when leaving block scope).
- //
- // It can be used to make calls to new() exception safe.
- //
- template<class T>
- class TVclPtr
- {
- public:
- TVclPtr(T* p = 0) : m_ptr(p) {}
- TVclPtr(TVclPtr<T>& src) : m_ptr(src.release()) {}
- TVclPtr& operator= (TVclPtr<T>& rhs) { reset(rhs.release()); return *this; }
- ~TVclPtr() { delete m_ptr; }
-
-
- operator T* () const { return m_ptr;}
- T& operator * () const { _ASSERTE(m_ptr); return *m_ptr; }
- T* operator-> () const { _ASSERTE(m_ptr); return m_ptr; }
- T** operator &()/*const*/ { return &m_ptr; }
- bool operator !() const { return m_ptr == 0; }
-
- bool operator == (T* rhs) const { return m_ptr == rhs;}
- bool operator == (const TVclPtr<T>& rhs) const { return m_ptr == rhs.m_ptr; }
- bool operator != (T* rhs) const { return m_ptr != rhs;}
- bool operator != (const TVclPtr<T>& rhs) const { return m_ptr != rhs.m_ptr; }
-
-
- T* get () const { return m_ptr; }
- T* release () { return reset(0); }
- T* reset (T* p = 0) { T* tmp = m_ptr; m_ptr = p; return tmp; }
-
- private:
- T* m_ptr;
- };
-
-
- // TComModule enhances ATL's CComModule
- // It is designed to support both in-process and out-of-process servers and handle
- // some VCL requirements.
- //
- class TComModule: public CComModule
- {
- public:
- TComModule(): m_ThreadID(0), m_bRun(true), m_bExe(false), m_InitProc(0), m_bAutomationServer(false)
- {}
-
- TComModule(TProcedure InitProcedure): m_ThreadID(0), m_bRun(true),
- m_bExe(true), m_InitProc(InitProcedure),
- m_bAutomationServer(false)
- {
- // Ensure OLE was properly initialized
- //
- _ASSERTE(!!m_InitOle);
-
- if (m_bExe && m_InitProc)
- {
- SaveInitProc = System::InitProc;
- System::InitProc = m_InitProc;
- }
- }
-
- ~TComModule(void)
- {
- if (m_bRun && m_bExe)
- {
- RevokeClassObjects();
- }
- }
-
- void DoFileAndObjectRegistration()
- {
- TSysCharSet DelimSet;
- DelimSet << '/' << '-';
- if (FindCmdLineSwitch("REGSERVER", DelimSet, true))
- {
- RegisterServer(TRUE);
- m_bRun = false;
- }
- else if (FindCmdLineSwitch("UNREGSERVER", DelimSet, true))
- {
- UnregisterServer();
- m_bRun = false;
- }
- else if (!(FindCmdLineSwitch("AUTOMATION", DelimSet, true) ||
- FindCmdLineSwitch("EMBEDDING", DelimSet, true)))
- RegisterServer(TRUE);
- if (m_bRun)
- #ifdef _ATL_SINGLEUSE_INSTANCING
- RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE);
- #else
- RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE);
- #endif
- else
- exit(EXIT_SUCCESS);
- }
-
- // Data members
- //
- DWORD m_ThreadID; // Thread identifier of module
- bool m_bRun; // Flags whether to run server
- bool m_bExe; // Flags Local server
- bool m_bAutomationServer; // Flags module's for Automation Server
- TProcedure m_InitProc; // Hold VCL's InitProc
- TInitOle m_InitOle; // Object to initialize OLE
-
- LONG Unlock();
-
- };
-
- // _Module is assumed to be a reference to a TComModule
- // User may define _Module to be a ref. to an instance of a class derived
- // from TComModule.
- //
- extern TComModule &_Module;
-
- #if !defined(__ATLCOM_H__)
- #include <atl\atlcom.h>
- #endif
- #include <shellapi.h>
- #if !defined(__ATLCTL_H__)
- #include <atl\atlctl.h>
- #endif
-
- #include <vcl.h>
- #include <databkr.hpp>
- #include <atl\axform.h>
-
- // Forward type Declaration
- //
- template <class T> class DELPHICLASS TWinControlAccess;
-
- // Forward function declarations
- //
- void __fastcall InitAtlServer(void);
-
- /* IDataBroker support */
-
- // IDataBrokerImpl class implements IDataBroker interface, and is
- // used to publish datasets residing in a TDataModule.
- //
- template <class DM, class T, class Intf, const IID* piid, const GUID* plibid>
- class ATL_NO_VTABLE IDataBrokerImpl: public IDispatchImpl<Intf, piid, plibid>
- {
- public:
- DM* m_DataModule;
-
- IDataBrokerImpl()
- {
- m_DataModule = new DM(NULL);
- }
- ~IDataBrokerImpl()
- {
- // Forces a reference to bdeprov.obj so that initialization code
- // is executed.
- //
- Bdeprov::UseBdeProv();
- m_DataModule->Free();
- }
-
- HRESULT IDataBroker_GetProviderNames(System::OleVariant &Result)
- {
- unsigned int TICount;
- _di_ITypeInfo TI;
- TVclPtr<Classes::TStringList> ProvProps(new TStringList);
-
- HRESULT hres = GetTypeInfoCount(&TICount);
- if (hres != S_OK)
- return hres;
-
- if (TICount)
- {
- hres = GetTypeInfo(0, 0, &TI);
- if (hres != S_OK)
- return hres;
- Databkr::EnumIProviderProps(TI, ProvProps);
- ::VariantClear(&(VARIANT&)Result);
- Result = Databkr::VarArrayFromStrings(ProvProps);
- }
- return S_OK;
- }
-
- // IDataBroker
- //
- HRESULT STDMETHODCALLTYPE GetProviderNames(System::OleVariant &Result)
- {
- ATLTRACE(_T("IDataBroker::GetProviderNames\n"));
- HRESULT hres;
- try
- {
- hres = static_cast<T*>(this)->IDataBroker_GetProviderNames(Result);
- }
- catch (Exception& e)
- {
- return (static_cast<T*>(this))->Error(e.Message.c_str());
- }
- return hres;
- }
- };
-
-
- // ISimpleFrameSite support
- //
- template <class T>
- class ATL_NO_VTABLE ISimpleFrameSiteImpl
- {
- public:
- // IUnknown
- STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
- _ATL_DEBUG_ADDREF_RELEASE_IMPL(IPersistImpl)
-
- // ISimpleFrameSite
- STDMETHOD(PreMessageFilter)(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp,
- LRESULT* plResult, DWORD* pdwCookie)
- {
- ATLTRACE(_T("ISimpleFrameImpl::PreMessageFilter\n"));
- T* pT = static_cast<T*>(this);
- return pT->ISimpleFrameSite_PreMessageFilter(hWnd, msg, wp, lp, plResult, pdwCookie);
- }
-
- STDMETHOD(PostMessageFilter)(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp,
- LRESULT* plResult, DWORD dwCookie)
- {
- ATLTRACE(_T("ISimpleFrameImpl::PostMessageFilter\n"));
- T* pT = static_cast<T*>(this);
- return pT->ISimpleFrameSite_PostMessageFilter(hWnd, msg, wp, lp, plResult, dwCookie);
- }
- };
-
- /* ActiveX control support */
-
- // TVclComControl is an ATL ActiveX control which encapsulates a VCL control
- // T is the user's class which implements the OLE Control.
- // TVCL is the VCL type which is exposed as an ActiveX Control.
- //
- template <class T, class TVCL>
- class ATL_NO_VTABLE TVclComControl: public CComControlBase, public CMessageMap
- {
- public:
- TVclComControl(void): m_VclCtl(0), m_VclWinCtl(0), m_hWnd(0),
- m_CtlWndProc(0), CComControlBase(m_hWnd)
- {
- m_bWindowOnly = TRUE;
- }
-
- ~TVclComControl(void)
- {
- if (m_VclCtl)
- {
- m_VclCtl->WindowProc = m_CtlWndProc;
- delete m_VclCtl;
- }
- if ((m_VclWinCtl) && ((TWinControl*)m_VclWinCtl != (TWinControl*)m_VclCtl))
- delete m_VclWinCtl;
- }
-
- // IOleObject support
- //
- HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite)
- {
- HRESULT hres = CComControlBase::IOleObject_SetClientSite(pClientSite);
- if (hres == S_OK)
- {
- if (m_spClientSite != NULL)
- {
- DWORD MiscFlags;
- hres = static_cast<T*>(this)->GetMiscStatus(DVASPECT_CONTENT, &MiscFlags);
-
- if (!SUCCEEDED(hres))
- return hres;
-
- // The following double checks that the registry entry indeed corresponds to
- // the value specified by our Control. (NOTE: IOleObject's implementation
- // looks up the value in the registry).
- //
- _ASSERTE(MiscFlags == static_cast<T*>(this)->_GetObjectMiscStatus());
-
- if (MiscFlags & OLEMISC_SIMPLEFRAME)
- {
- m_spClientSite->QueryInterface(IID_ISimpleFrameSite,
- (void**)&m_spSimpleFrameSite);
- }
-
- // Initialize the helper class used to get ambient properties from the container
- m_AmbientDriver.Bind(m_spClientSite);
-
- // Get ambient properties from the container and update the control
- static_cast<T*>(this)->OnAmbientPropertyChange(0);
-
- // Enable Ctl3D style
- m_VclWinCtl->Perform(CM_PARENTCTL3DCHANGED, 1, 1);
- }
- else
- {
- m_spSimpleFrameSite = NULL;
- m_AmbientDriver = NULL;
- }
- }
- else
- {
- m_spClientSite = NULL;
- m_AmbientDriver = NULL;
- }
- return hres;
- }
-
- // IPersistStreamInit support
- //
- HRESULT IPersistStreamInit_Save(LPSTREAM pStm, BOOL /* fClearDirty */, ATL_PROPMAP_ENTRY* pMap)
- {
- try
- {
- ::SaveVCLComponentToStream(m_VclCtl, pStm);
- //!?? Clear fClearDirty flag
- }
- catch (Exception& e)
- {
- return (static_cast<T*>(this))->Error(e.Message.c_str());
- }
- return S_OK;
- }
-
- HRESULT IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap)
- {
- try
- {
- ::LoadVCLComponentFromStream(m_VclCtl, pStm);
- }
- catch (Exception& e)
- {
- return (static_cast<T*>(this))->Error(e.Message.c_str());
- }
- return S_OK;
- }
-
- // ISimpleFrameSite support
- //
- HRESULT ISimpleFrameSite_PreMessageFilter(HWND hWnd, UINT msg, WPARAM wp,
- LPARAM lp, LRESULT* plResult, DWORD* pdwCookie)
- {
- if (m_spSimpleFrameSite)
- return m_spSimpleFrameSite->PreMessageFilter(hWnd, msg, wp, lp,
- plResult, pdwCookie);
- else
- return S_OK;
- }
-
- HRESULT ISimpleFrameSite_PostMessageFilter(HWND hWnd, UINT msg, WPARAM wp,
- LPARAM lp, LRESULT* plResult, DWORD dwCookie)
- {
- if (m_spSimpleFrameSite)
- return m_spSimpleFrameSite->PostMessageFilter(hWnd, msg, wp, lp,
- plResult, dwCookie);
- else
- return S_OK;
- }
-
-
- // IPropertyNotifySink Support methods
- //
- // NOTE: If your control class derives from IPropertyNotifySink, this method calls
- // CFirePropNotifyEvent::FireOnRequestEdit to notify all connected IPropertyNotifySink interfaces
- // that the specified control property is about to change. If your control class does not derive
- // from IPropertyNotifySink, this method returns S_OK.
- //
- HRESULT FireOnRequestEdit(DISPID dispID)
- {
- T* pT = static_cast<T*>(this);
- return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
- }
-
- // If your control class derives from IPropertyNotifySink, this method calls
- // CFirePropNotifyEvent::FireOnChanged to notify all connected IPropertyNotifySink interfaces
- // that the specified control property has changed. If your control class does not derive from
- // IPropertyNotifySink, this method returns S_OK
- //
- HRESULT FireOnChanged(DISPID dispID)
- {
- T* pT = static_cast<T*>(this);
- return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
- }
-
- // Retrieves pointer to requested interface
- // NOTE: Limited to interfaces listed in COM map table
- //
- virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
- {
- T* pT = static_cast<T*>(this);
- return pT->_InternalQueryInterface(iid, ppv);
- }
-
- // Creates underlying window of the control.
- // NOTE: You may override this method to do something other than create an window (for
- // example, to create two windows, one of which becomes a toolbar for your control).
- //
- HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
- {
- T* pT = static_cast<T*>(this);
- return pT->Create(hWndParent, rcPos);
- }
-
- // Returns the handle of the control, if successful. Otherwise, returns NULL.
- //
- HWND Create(HWND hWndParent, RECT& rcPos);
-
- // Sets the Window's show state (See ::ShowWindow of WIN32 SDK for details on 'nCmdShow')
- //
- BOOL ShowWindow(int nCmdShow)
- {
- _ASSERTE(m_hWnd);
- return ::ShowWindow(m_hWnd, nCmdShow);
- }
-
- // Overridable Message Handler method of Control.
- // NOTE: You may intercept messages in your control via an ATL Message Map.
- // The default implementation of this method is to dispatch messages
- // via the Message Map. If the message was not handled via a message
- // map, the message is dispatched to the underlying VCL handler.
- //
- virtual void ControlWndProc(Messages::TMessage& Message);
-
- // Procedure handling messages of this control
- //
- virtual void __fastcall WndProc(Messages::TMessage& Message);
-
- // Method which destroys and re-create the control's window.
- // NOTE: This may be necessary if you need to change the window's style bits.
- //
- void RecreateWnd();
-
- // Data members
- //
- HWND m_hWnd; // Underlying Window Handle of our Control
-
- protected:
- virtual void InitializeControl()
- {}
-
- void Initialize();
-
-
- TWinControlAccess<TWinControl>* m_VclWinCtl;
- TWinControlAccess<TVCL>* m_VclCtl;
- TAutoDriver<IDispatch> m_AmbientDriver;
-
- private:
- TWndMethod m_CtlWndProc;
- CComPtr<ISimpleFrameSite> m_spSimpleFrameSite;
- };
-
-
-
- // TVclComControl::Initialize
- //
- template <class T, class TVCL> void
- TVclComControl<T, TVCL>::Initialize(void)
- {
- // Retrieve handle to reflector Window defined in AXCTRLS unit
- //
- HWND hwndParkingWindow = Axctrls::ParkingWindow();
-
- // Create VCL Object Wrapper for our Control
- //
- // jmt m_VclCtl = new TWinControlAccess<TVCL>(hwndParkingWindow);
- m_VclCtl = (TWinControlAccess<TVCL>*)(TVCL::CreateParentedControl(__classid(TWinControlAccess<TVCL>), (int)hwndParkingWindow));
-
- // Test whether our control requires message reflection and create a reflector window if yes
- //
- if (m_VclCtl->ControlStyle.Contains(csReflector))
- (TWinControl*)m_VclWinCtl = ::CreateReflectorWindow(hwndParkingWindow, m_VclCtl);
- else
- (TWinControl*)m_VclWinCtl = (TWinControl*)m_VclCtl;
-
- // Update the Window Procedure variables
- //
- m_CtlWndProc = m_VclCtl->WindowProc;
- m_VclCtl->WindowProc = WndProc;
-
- // Invoke virtual allowing Control to perform additional initialization
- //
- InitializeControl();
- ATLTRACE(_T("VCL control created and initialized\n"));
- }
-
-
- // TVclComControl::ReCreateWnd
- //
- template <class T, class TVCL> void
- TVclComControl<T, TVCL>::RecreateWnd()
- {
- if (m_VclWinCtl->HandleAllocated())
- {
- RECT CtlBounds = m_VclWinCtl->BoundsRect;
- HWND PrevWnd = ::GetWindow(m_VclWinCtl->Handle, GW_HWNDPREV);
-
- // set ATL window handle to NULL to prevent InPlaceDeactiveate()
- // from destroying the VCL control window too soon
- //
- m_hWndCD = NULL;
- IOleInPlaceObject_InPlaceDeactivate();
- m_VclWinCtl->DoDestroyHandle();
- m_VclWinCtl->UpdateControlState();
- if (InPlaceActivate(m_bUIActive ? OLEIVERB_INPLACEACTIVATE : OLEIVERB_HIDE,
- &CtlBounds) == S_OK)
- ::SetWindowPos(m_VclWinCtl->Handle, PrevWnd, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- }
- }
-
-
- // TVclComControl::Create
- //
- template <class T, class TVCL> HWND
- TVclComControl<T, TVCL>::Create(HWND hWndParent, RECT& rcPos)
- {
- _ASSERTE(m_VclCtl);
-
- // Set the parent handle here because with a parking window of NULL. The
- // window is not created until the parent is set.
- //
- m_VclWinCtl->ParentWindow = hWndParent;
- m_VclWinCtl->BoundsRect = rcPos;
-
- // For ActiveForms the window handle will be NULL at this point; so, force create.
- //
- m_VclWinCtl->HandleNeeded();
-
- // For ActiveForms again, the window will not be visible. So, show it.
- //
- m_VclWinCtl->Visible = true;
-
- // Update and return handle
- //
- m_hWnd = m_VclWinCtl->GetWindowHandle();
- return m_hWnd;
- }
-
-
- // TVclComControl::ControlWndProc
- //
- template <class T, class TVCL> void
- TVclComControl<T, TVCL>::ControlWndProc(Messages::TMessage& Message)
- {
- if ((Message.Msg >= OCM_BASE) && (Message.Msg < OCM_BASE + WM_USER))
- Message.Msg = Message.Msg + (CN_BASE - OCM_BASE);
-
- // Allow ATL message maps to intercept messages before they are dispatch to VCL handlers
- //
- if (!ProcessWindowMessage(m_VclCtl->GetWindowHandle(), Message.Msg,
- Message.WParam, Message.LParam,
- *((LRESULT*)(&Message.Result)), 0))
- m_CtlWndProc(Message);
-
- if ((Message.Msg >= CN_BASE) && (Message.Msg < CN_BASE + WM_USER))
- Message.Msg = Message.Msg - (CN_BASE - OCM_BASE);
- }
-
-
- // TvclComControl::WndProc
- // Procedure handling messages of this control
- //
- template <class T, class TVCL> void __fastcall
- TVclComControl<T, TVCL>::WndProc(Messages::TMessage& Message)
- {
- DWORD dwCookie;
- HWND Handle = m_VclCtl->GetWindowHandle();
- bool FilterMessage = ((Message.Msg < CM_BASE) || (Message.Msg >= 0xC000)) &&
- m_spSimpleFrameSite && m_bInPlaceActive;
- if (FilterMessage)
- {
- if (m_spSimpleFrameSite->PreMessageFilter(Handle,
- Message.Msg, Message.WParam,
- Message.LParam, (LRESULT*)&Message.Result,
- &dwCookie) == S_FALSE)
- return;
- }
-
- T* pT = static_cast<T*>(this);
- CComPtr<IOleControlSite> spSite;
- switch (Message.Msg)
- {
- case WM_SETFOCUS:
- case WM_KILLFOCUS:
- ControlWndProc(Message);
- m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&spSite);
- if (spSite)
- spSite->OnFocus(Message.Msg == WM_SETFOCUS);
- break;
-
- case CM_VISIBLECHANGED:
- if ((TWinControl*)m_VclCtl != (TWinControl*)m_VclWinCtl)
- m_VclWinCtl->Visible = m_VclCtl->Visible;
- if (!(m_VclWinCtl->Visible))
- IOleInPlaceObject_UIDeactivate();
- ControlWndProc(Message);
- break;
-
- case CM_RECREATEWND:
- if ((m_bInPlaceActive) && ((TWinControl*)m_VclCtl == (TWinControl*)m_VclWinCtl))
- RecreateWnd();
- else
- {
- ControlWndProc(Message);
- pT->SendOnViewChange(DVASPECT_CONTENT);
- }
- break;
-
- case CM_INVALIDATE:
- case WM_SETTEXT:
- ControlWndProc(Message);
- if (!m_bInPlaceActive)
- pT->SendOnViewChange(DVASPECT_CONTENT);
- break;
-
- case WM_NCHITTEST:
- ControlWndProc(Message);
- if (Message.Result == HTTRANSPARENT)
- Message.Result = HTCLIENT;
- break;
-
- default:
- ControlWndProc(Message);
- }
- if (FilterMessage)
- m_spSimpleFrameSite->PostMessageFilter(Handle, Message.Msg,
- Message.WParam,
- Message.LParam,
- (LRESULT*)&Message.Result,
- dwCookie);
- }
-
-
- // TWinControlAccess: Template which wraps the Window interface of an ActiveX Control
- //
- template <class T>
- class TWinControlAccess: public T
- {
- __fastcall virtual TWinControlAccess(Classes::TComponent* AOwner): T(AOwner) {}
- public:
- __fastcall TWinControlAccess(HWND ParentWindow): T(ParentWindow) {}
- HWND GetWindowHandle(void) {return WindowHandle;}
- void DoDestroyHandle(void) {DestroyHandle();}
- };
-
-
- // TVclControlImpl
- //
- template <class T, // User class implementing Control
- class TVCL, // Underlying VCL type used in One-Step Conversion
- const CLSID* pclsid, // Class ID of Control
- const IID* piid, // Primary interface of Control
- const IID* peventsid, // Event (outgoing) interface of Control
- const GUID* plibid> // GUID of TypeLibrary
- class ATL_NO_VTABLE TVclControlImpl:
- public CComObjectRootEx<CComObjectThreadModel>,
- public CComCoClass<T, pclsid>,
- public TVclComControl<T, TVCL>,
- public IProvideClassInfo2Impl<pclsid, peventsid, plibid>,
- public IPersistStreamInitImpl<T>,
- public IPersistStorageImpl<T>,
- public IQuickActivateImpl<T>,
- public IOleControlImpl<T>,
- public IOleObjectImpl<T>,
- public IOleInPlaceActiveObjectImpl<T>,
- public IViewObjectExImpl<T>,
- public IOleInPlaceObjectWindowlessImpl<T>,
- public IDataObjectImpl<T>,
- public ISpecifyPropertyPagesImpl<T>,
- public IConnectionPointContainerImpl<T>,
- public IPropertyNotifySinkCP<T, CComDynamicUnkArray>,
- public ISupportErrorInfo,
- public ISimpleFrameSiteImpl<T>
- {
- public:
-
- TVclControlImpl()
- {}
-
- ~TVclControlImpl()
- {}
-
- // Returns pointer to outer IUnknown
- //
- virtual IUnknown* GetControllingUnknown()
- {
- return (static_cast<T*>(this))->GetUnknown();
- }
-
- // Empty Message Map provides default implementation of 'ProcessWindowMessage'
- //
- BEGIN_MSG_MAP(TVclControlImpl)
- END_MSG_MAP()
-
- // Map of connection points supported
- //
- BEGIN_CONNECTION_POINT_MAP(T)
- CONNECTION_POINT_ENTRY(*peventsid)
- CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
- END_CONNECTION_POINT_MAP()
-
- // This macro declares a static routine which returns the default OLEMISC_xxxx
- // flags used for controls. The macro may be redefined in the derived class
- // to specify other OLEMISC_xxxx values.
- //
- DECLARE_OLEMISC_FLAGS(dwDefaultControlMiscFlags);
-
- // Verbs supported by Control. Provides default implementation of _GetVerbs()
- // This table can be redefined in the user's class if the latter supports additional
- // Verbs (or does not want the default 'Properties' verb).
- //
- BEGIN_VERB_MAP()
- VERB_ENTRY(0, L"Properties")
- END_VERB_MAP()
-
- // IOleInPlaceObject
- //
- STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
- {
- try
- {
- if (m_VclWinCtl)
- m_VclWinCtl->SetBounds(prcPos->left, prcPos->top,
- prcPos->right - prcPos->left, prcPos->bottom - prcPos->top);
- }
- catch (Exception& e)
- {
- return (static_cast<T*>(this))->Error(e.Message.c_str());
- }
- return S_OK;
- }
-
-
- HRESULT FinalConstruct()
- {
- try
- {
- Initialize();
- }
- catch(Exception &e)
- {
- return (static_cast<T*>(this))->Error(e.Message.c_str());
- }
- return S_OK;
- return S_OK;
- }
-
- void FinalRelease()
- {}
-
- // IViewObjectEx
- //
- STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
- {
- ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n"));
- *pdwStatus = VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE;
- return S_OK;
- }
-
- // ISupportErrorInfo
- //
- STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
- {
- ATLTRACE(_T("ISupportErrorInfo::InterfaceSupportsErrorInfo\n"));
- T* pT = static_cast<T*>(this);
- const _ATL_INTMAP_ENTRY *pentries = pT->_GetEntries();
-
- while (pentries->piid)
- {
- if (InlineIsEqualGUID(*(pentries->piid),riid))
- return S_OK;
- pentries++;
- }
- return S_FALSE;
- }
-
- // IOleControl
- // The following implementation supports BACKCOLOR, FORECOLOR, and FONT ambient
- // properties. Note that a VCL control will ignore the container's BACKCOLOR
- // property unless the control's ParentColor property is True. FORECOLOR and
- // FONT properties are ignored unless the control's ParentFont property is True.
- //
- STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
- {
- ATLTRACE(_T("IOleControl::OnAmbientPropertyChange\n"));
- ATLTRACE(_T(" -- DISPID = %d (%d)\n"), dispid);
- if (m_VclWinCtl == NULL || m_AmbientDriver == NULL)
- return S_OK;
- if (dispid == DISPID_AMBIENT_BACKCOLOR ||
- dispid == 0)
- {
- TAutoArgs<0> arg;
- HRESULT hres = m_AmbientDriver.OlePropertyGet(DISPID_AMBIENT_BACKCOLOR, arg);
- if (hres != S_OK)
- return hres;
- m_VclWinCtl->Perform(CM_PARENTCOLORCHANGED, 1, arg.GetRetVariant());
- }
- if (dispid == DISPID_AMBIENT_FORECOLOR ||
- dispid == DISPID_AMBIENT_FONT ||
- dispid == 0)
- {
- TAutoArgs<0> arg;
- TVclPtr<TFont> pFont = new TFont;
- HRESULT hres = m_AmbientDriver.OlePropertyGet(DISPID_AMBIENT_FORECOLOR, arg);
- if (hres != S_OK)
- return hres;
- pFont->Color = (int)arg.GetRetVariant();
- hres = m_AmbientDriver.OlePropertyGet(DISPID_AMBIENT_FONT, arg);
- if (hres != S_OK)
- return hres;
- SetOleFont(pFont, (IFontDisp*)(IUnknown*)arg.GetRetVariant());
- m_VclWinCtl->Perform(CM_PARENTFONTCHANGED, 1, int(pFont.get()));
- }
- return S_OK;
- }
-
- // IAtlSubCtl
- //
- HRESULT OnDraw(ATL_DRAWINFO& di)
- {
- try
- {
- if (m_VclCtl)
- m_VclCtl->PaintTo(di.hdcDraw, di.prcBounds->left, di.prcBounds->top);
- }
- catch (Exception& e)
- {
- return (static_cast<T*>(this))->Error(e.Message.c_str());
- }
- return S_OK;
- }
- };
-
- // TValidateLicense - Standard implementation of 'IsLicenseValid' that simply returns
- // TRUE. When Control Licensing support is enabled, the Wizard
- // automatically assigns your control a GUID as the Runtime License
- // string. However, your control still needs to validate whether the
- // it is licensed on the machine (before handing out the runtime
- // license string for example). This class provides a standard implementation
- // of the validation routine that simply returns TRUE.
- //
- class TValidateLicense
- {
- public:
- static BOOL IsGUIDInFile(const WCHAR *szGUID, const TCHAR *szLicFileName)
- {
- LPCTSTR pName = 0;
-
- // Find name of LicFileName
- //
- OFSTRUCT ofs;
- ZeroMemory(&ofs, sizeof(ofs));
- ofs.cBytes = sizeof(OFSTRUCT);
-
- // We'll look for the license file in the directory of the OCX..
- // Then in the current, app, Windows, System or PATH directories!!
- //
- TCHAR szModule[_MAX_PATH];
- ::GetModuleFileName(_Module.GetModuleInstance(), szModule, sizeof(szModule));
- TCHAR szDir[_MAX_DIR];
- TCHAR szDrv[_MAX_DRIVE];
- _tfnsplit(szModule, szDrv, szDir, 0, 0);
- _tfnmerge(szModule, szDrv, szDir, 0, 0);
- lstrcat(szModule, szLicFileName);
- if (::OpenFile(szModule, &ofs, OF_EXIST) != HFILE_ERROR ||
- ::OpenFile(szLicFileName, &ofs, OF_EXIST) != HFILE_ERROR)
- {
- pName = ofs.szPathName;
- }
- else
- {
- // Could not find file anywhere
- //
- ATLTRACE(_T("Could not find License File\n"));
- return false;
- }
-
- // Create a TStringList and load from the file
- //
- _ASSERTE(pName);
- TVclPtr<TStringList> pList = new TStringList;
- pList->LoadFromFile(pName);
- int index = pList->IndexOf(AnsiString(szGUID));
- return (index != -1);
- }
- };
-
- // TLicenseString
- // Template built around the runtime license string of a Control.
- // 'VerifyLicenseKey' compares string passed in to the runtime license key
- // 'GetLicenseKey' returns the runtime license key
- // 'IsLicenseValid' delegates to T::IsLicenseValid allowing a separate class to
- // handle the license verification.
- //
- template <class T>
- class TLicenseString
- {
- protected:
- static BOOL VerifyLicenseKey(BSTR str)
- {
- ATLTRACE(_T("TLicenseString::VerifyLicenseKey\n"));
- return !lstrcmpW(str, T::GetLicenseString());
- }
-
- static BOOL GetLicenseKey(DWORD /*dwReserved*/, BSTR *pStr)
- {
- ATLTRACE(_T("TLicenseString::GetLicenseKey\n"));
- *pStr = ::SysAllocString(T::GetLicenseString());
- return TRUE;
- }
-
- static BOOL IsLicenseValid()
- {
- ATLTRACE(_T("TLicenseString::IsLicenseValid\n"));
- return T::IsLicenseValid();
- }
- };
-
-
- #include <axctrls.hpp>
- // TVCLPropertyPage
- //
- template <class T, const CLSID* pclsid, class ppclass>
- class ATL_NO_VTABLE TVCLPropertyPage: public CComObjectRootEx<CComSingleThreadModel>,
- public IUnknown,
- public CComCoClass<T, pclsid>
- {
- public:
- TVCLPropertyPage(void): m_PPImpl(0), m_InnerUnk(0)
- {}
- ~TVCLPropertyPage()
- {}
-
- DECLARE_PROTECT_FINAL_CONSTRUCT()
-
- HRESULT FinalConstruct(void)
- {
- ATLTRACE(_T("TVCLPropertyPage::FinalConstruct\n"));
- try
- {
- HRESULT hres = CComObjectRootEx<CComSingleThreadModel>::FinalConstruct();
- if (hres != S_OK)
- return hres;
- IUnknown* pUnk = (static_cast<T*>(this))->GetUnknown();
- m_PPImpl = new TPropertyPageImpl(_di_IUnknown(pUnk));
- m_PPImpl->GetInterface(IID_IUnknown, &m_InnerUnk);
- m_PPImpl->PropertyPage = new ppclass((TComponent*)NULL);
- m_PPImpl->InitPropertyPage();
- }
- catch (Exception& e)
- {
- return (static_cast<T*>(this))->Error(e.Message.c_str());
- }
- return S_OK;
- }
-
- void FinalRelease(void)
- {
- ATLTRACE(_T("TVCLPropertyPage::FinalRelease\n"));
- try
- {
- if (m_PPImpl->PropertyPage)
- delete m_PPImpl->PropertyPage;
- if (m_PPImpl)
- delete m_PPImpl;
- CComObjectRootEx<CComSingleThreadModel>::FinalRelease();
- }
- catch (Exception& e)
- {
- // don't propagate exception
- }
- }
-
- // Data members
- //
- TPropertyPageImpl* m_PPImpl;
- IUnknown* m_InnerUnk;
- };
-
-
- // TComServerRegistrar class performs registration for a COM server.
- // An instance of this class is typically created via the
- // DECLARE_COMSERVER_REGISTRY macro.
- //
- class TComServerRegistrar
- {
- public:
- TComServerRegistrar() : m_ClassID(CLSID_NULL)
- {
- Init();
- }
- TComServerRegistrar(const CLSID& clsid, AnsiString progID,
- AnsiString description) : m_ClassID(clsid), m_ProgID(progID),
- m_Description(description)
- {
- Init();
- }
- ~TComServerRegistrar()
- {}
-
- virtual HRESULT UpdateRegistry(bool Register);
-
- // Helpers to create/delete registry keys
- //
- static void CreateRegKey(AnsiString Key, AnsiString ValueName, AnsiString Value);
- static void DeleteRegKey(AnsiString Key);
- static void NukeRegKey(AnsiString Key);
-
- protected:
- AnsiString m_ProgID;
- AnsiString m_ClassKey;
- AnsiString m_Description;
- AnsiString m_ServerType;
- WideString m_ModuleName;
- CLSID m_ClassID;
-
- // Helper routine to initialize some data members of class
- //
- void Init();
- };
-
- // TTypedComServerRegistrar class performs registration for a COM server
- // which contains a type library (i.e., an automation server).
- // An instance of this class is typically created via the
- // DECLARE_TYPED_COMSERVER_REGISTRY macro.
- //
- class TTypedComServerRegistrar: public TComServerRegistrar
- {
- public:
- TTypedComServerRegistrar(): TComServerRegistrar() {}
-
- TTypedComServerRegistrar(const CLSID& clsid, AnsiString ProgID):
- TComServerRegistrar(clsid, ProgID, NULL)
- {}
-
- // Overriden to perform additional Registration tasks
- //
- HRESULT UpdateRegistry(bool Register);
- };
-
-
- // TRemoteDataModuleRegistrar
- //
- class TRemoteDataModuleRegistrar : public TTypedComServerRegistrar
- {
- public:
- TRemoteDataModuleRegistrar() : TTypedComServerRegistrar() {}
-
- TRemoteDataModuleRegistrar(const CLSID& clsid, AnsiString ProgID):
- TTypedComServerRegistrar(clsid, ProgID)
- {}
-
- // Overriden to perform additional Registration tasks
- //
- virtual HRESULT UpdateRegistry(bool Register);
- };
-
-
- // TAxControlRegistrar class performs registration for an ActiveX control.
- // An instance of this class is typically created via the
- // DECLARE_ACTIVEXCONTROL_FACTORY macro.
- //
- class TAxControlRegistrar: public TTypedComServerRegistrar
- {
- public:
- TAxControlRegistrar(): m_BitmapID(0), m_MiscFlags(dwDefaultControlMiscFlags), m_Verbs(0)
- {}
-
- TAxControlRegistrar(const CLSID& clsid, // CLSID of Object
- AnsiString ProgID, // ProgId of Object
- int BitmapID, // Index of ToolboxBitmap32 res.
- DWORD MiscFlags = dwDefaultControlMiscFlags, // Object MISC_xxx flags
- const OLEVERB *verbs = 0) : // Array of Verbs
- m_BitmapID(BitmapID),
- m_MiscFlags(MiscFlags),
- m_Verbs(verbs),
- TTypedComServerRegistrar(clsid, ProgID)
- {}
-
- // Overriden to perform additional Registration tasks
- //
- virtual HRESULT UpdateRegistry(bool Register);
-
- protected:
- int m_BitmapID; // Index of ToolboxBitmap32 Resource
- DWORD m_MiscFlags; // Inf. about Control's Designer's/behavior's aspect
- const OLEVERB* m_Verbs; // Array of OLEVERBs support be Control
- };
-
-
- // VCL_CONTROL_COM_INTERFACE_ENTRIES
- //
- // This macro defines the entries of the required Interfaces for exposing a VCL
- // component as an ActiveX Control
- //
- #define VCL_CONTROL_COM_INTERFACE_ENTRIES(intf) \
- COM_INTERFACE_ENTRY_IMPL(IViewObjectEx) \
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx) \
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx) \
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless) \
- COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless) \
- COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject) \
- COM_INTERFACE_ENTRY_IMPL(IOleControl) \
- COM_INTERFACE_ENTRY_IMPL(IOleObject) \
- COM_INTERFACE_ENTRY_IMPL(IQuickActivate) \
- COM_INTERFACE_ENTRY_IMPL(IPersistStorage) \
- COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit) \
- COM_INTERFACE_ENTRY_IMPL(ISpecifyPropertyPages) \
- COM_INTERFACE_ENTRY_IMPL(IDataObject) \
- COM_INTERFACE_ENTRY_IMPL(ISimpleFrameSite) \
- COM_INTERFACE_ENTRY(IProvideClassInfo) \
- COM_INTERFACE_ENTRY(IProvideClassInfo2) \
- COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) \
- COM_INTERFACE_ENTRY(ISupportErrorInfo) \
- COM_INTERFACE_ENTRY(intf) \
- COM_INTERFACE_ENTRY2(IDispatch, intf)
-
-
- // VCLCONTROL_IMPL
- // This macro is used to encapsulate the various base classes an ActiveX VCL Control derives from.
- //
- #define VCLCONTROL_IMPL(cppClass, CoClass, VclClass, intf, EventID) \
- public TVclControlImpl<cppClass, VclClass, &CLSID_##CoClass, &IID_##intf, &EventID, &LIBID_##CoClass>,\
- public IDispatchImpl<intf, &IID_##intf, &LIBID_##CoClass>, \
- public TEvents_##CoClass<cppClass>
-
-
- #define AUTOOBJECT_COM_INTERFACE_ENTRIES(intf) \
- COM_INTERFACE_ENTRY(intf) \
- COM_INTERFACE_ENTRY2(IDispatch, intf)
-
- #define BEGIN_AUTOOBJECT_COM_MAP(coclass, intf) \
- BEGIN_COM_MAP(T##coclass) \
- AUTOOBJECT_COM_INTERFACE_ENTRIES(intf)
-
- #define END_AUTOOBJECT_COM_MAP END_COM_MAP
-
- #define PROPERTYPAGE_COM_INTERFACE_ENTRIES \
- COM_INTERFACE_ENTRY(IUnknown) \
- COM_INTERFACE_ENTRY_AGGREGATE(IID_IPropertyPage, m_InnerUnk) \
- COM_INTERFACE_ENTRY_AGGREGATE(IID_IPropertyPage2, m_InnerUnk)
-
- #define BEGIN_PROPERTYPAGE_COM_MAP(coclass) \
- BEGIN_COM_MAP(T##coclass) \
- PROPERTYPAGE_COM_INTERFACE_ENTRIES
-
- #define END_PROPERTYPAGE_COM_MAP END_COM_MAP
-
- #define AUTOOBJECT_IMPL(cppClass, CoClass, intf) \
- public CComObjectRootEx<CComObjectThreadModel>, \
- public CComCoClass<cppClass, &CLSID_##CoClass>, \
- public IDispatchImpl<intf, &IID_##intf, &LIBID_##CoClass>
-
- #define REMOTEDATAMODULE_IMPL(cppClass, CoClass, VclClass, intf) \
- public CComObjectRootEx<CComObjectThreadModel>, \
- public CComCoClass<cppClass, &CLSID_##CoClass>, \
- public IDataBrokerImpl<VclClass, cppClass, intf, &IID_##intf, &LIBID_##CoClass>
-
- #define DUALINTERFACE_IMPL(coclass, intf) \
- public IDispatchImpl<##intf, &IID_##intf, &LIBID_##coclass>
-
- #define DUALINTERFACE_ENTRY(i) \
- COM_INTERFACE_ENTRY(i)
-
- #define PROPERTYPAGE_IMPL(cppClass, CoClass, VclClass) \
- public TVCLPropertyPage<cppClass, &CLSID_##CoClass, VclClass>
-
- #define UPDATE_REGISTRY_METHOD(code) \
- static HRESULT WINAPI UpdateRegistry(BOOL bRegister) \
- { \
- HRESULT hres; \
- try \
- { \
- code \
- } \
- catch (Exception& e) \
- { \
- hres = Error(e.Message.c_str()); \
- } \
- return hres; \
- }
-
- #define DECLARE_COMSERVER_REGISTRY(progid, desc) \
- UPDATE_REGISTRY_METHOD( \
- TComServerRegistrar CSR(GetObjectCLSID(), progid, desc); \
- hres = CSR.UpdateRegistry(bRegister);)
-
- #define DECLARE_TYPED_COMSERVER_REGISTRY(progid) \
- UPDATE_REGISTRY_METHOD( \
- TTypedComServerRegistrar TCSR(GetObjectCLSID(), progid); \
- hres = TCSR.UpdateRegistry(bRegister);)
-
- #define DECLARE_REMOTEDATAMODULE_REGISTRY(progid) \
- UPDATE_REGISTRY_METHOD( \
- TRemoteDataModuleRegistrar TCSR(GetObjectCLSID(), progid); \
- hres = TCSR.UpdateRegistry(bRegister);)
-
- #define DECLARE_ACTIVEXCONTROL_REGISTRY(progid, idbmp) \
- UPDATE_REGISTRY_METHOD( \
- TAxControlRegistrar AXCR(GetObjectCLSID(), progid, idbmp, _GetObjectMiscStatus(), _GetVerbs()); \
- hres = AXCR.UpdateRegistry(bRegister);)
-
-
- #pragma option pop
-
- #endif //__ATLVCL_H_
-
-